home *** CD-ROM | disk | FTP | other *** search
- head 1.6;
- branch ;
- access ;
- symbols sprited:1.5.1;
- locks ; strict;
- comment @ * @;
-
-
- 1.6
- date 92.01.21.16.27.07; author rab; state Exp;
- branches ;
- next 1.5;
-
- 1.5
- date 90.09.11.14.27.16; author kupfer; state Exp;
- branches 1.5.1.1;
- next 1.4;
-
- 1.4
- date 89.09.15.12.08.48; author douglis; state Exp;
- branches ;
- next 1.3;
-
- 1.3
- date 88.07.25.13.12.45; author ouster; state Exp;
- branches ;
- next 1.2;
-
- 1.2
- date 88.07.21.09.36.33; author ouster; state Exp;
- branches ;
- next 1.1;
-
- 1.1
- date 88.06.10.16.23.37; author ouster; state Exp;
- branches ;
- next ;
-
- 1.5.1.1
- date 91.12.02.20.05.34; author kupfer; state Exp;
- branches ;
- next ;
-
-
- desc
- @@
-
-
- 1.6
- log
- @Fixed handling of %[^] pattern where no chars
- are accepted (ie: first streamChar matches a
- pattern char). Must not update assignedFields
- and must abort outer 'for' loop.
- @
- text
- @/*
- * vfscanf.c --
- *
- * Source code for the "vfscanf" library procedure.
- *
- * Copyright 1988 Regents of the University of California
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /sprite/src/lib/c/stdio/RCS/vfscanf.c,v 1.5 90/09/11 14:27:16 kupfer Exp Locker: rab $ SPRITE (Berkeley)";
- #endif not lint
-
- #include <sprite.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include <varargs.h>
-
- #ifndef TRUE
- #define TRUE 1
- #endif
- #ifndef FALSE
- #define FALSE 0
- #endif
-
- /*
- * Maximum number of bytes in allowable ASCII representation of a
- * floating-point number:
- */
-
- #define MAX_FLOAT_SIZE 350
- /*
- *----------------------------------------------------------------------
- *
- * vfscanf --
- *
- * This utility routine does all of the real work of scanning
- * fields under control of a format string. It is called by
- * scanf, fscanf, and sscanf.
- *
- * Results:
- * Values addressed by elements of args are modified to hold
- * values scanned from stream. The return value is a count of
- * the number of fields successfully scanned from stream, or
- * EOF if no characters could be input from stream.
- *
- * Side effects:
- * Information is input from stream.
- *
- *----------------------------------------------------------------------
- */
-
- int
- vfscanf(stream, format, args)
- register FILE *stream; /* Where to read characters for parsing. */
- register char *format; /* Contains literal text and format control
- * sequences indicating how args are to be
- * scanned. See the man page for details. */
- va_list args; /* Addresses of a variable number of arguments
- * to be modified. */
- {
- int suppress; /* TRUE means scan value but don't actual
- * modify an element of args. */
- int storeShort; /* TRUE means store a short value. */
- int storeLong; /* TRUE means store a long value. */
- int width; /* Field width. */
- register char formatChar; /* Current character from format string.
- * Eventually it ends up holding the format
- * type (e.g. 'd' for decimal). */
- register int streamChar; /* Next character from stream. */
- int assignedFields; /* Counts number of successfully-assigned
- * fields. */
- int base; /* Gives base for numbers: 0 means float,
- * -1 means not a number.
- */
- int sign; /* TRUE means negative sign. */
- char buf[MAX_FLOAT_SIZE+1];
- /* Place to accumulate floating-point
- * number for processing. */
- register char *ptr = (char *) NIL;
- char *savedPtr, *end, *firstPtr;
-
- assignedFields = 0;
- streamChar = getc(stream);
- if (streamChar == EOF) {
- return(EOF);
- }
-
- /*
- * The main loop is to scan through the characters in format.
- * Anything but a '%' must match the next character from stream.
- * A '%' signals the start of a format field; the formatting
- * information is parsed, the next value is scanned from the stream
- * and placed in memory, and the loop goes on.
- */
-
- for (formatChar = *format; (formatChar != 0) && (streamChar != EOF);
- format++, formatChar = *format) {
-
- /*
- * A white-space format character matches any number of
- * white-space characters from the stream.
- */
-
- if (isspace(formatChar)) {
- while (isspace(streamChar)) {
- streamChar = getc(stream);
- }
- continue;
- }
-
- /*
- * Any character but % must be matched exactly by the stream.
- */
-
- if (formatChar != '%') {
- if (streamChar != formatChar) {
- break;
- }
- streamChar = getc(stream);
- continue;
- }
-
- /*
- * Parse off the format control fields.
- */
-
- suppress = FALSE;
- storeLong = FALSE;
- storeShort = FALSE;
- width = -1;
- format++;
- formatChar = *format;
- if (formatChar == '*') {
- suppress = TRUE;
- format++;
- formatChar = *format;
- }
- if (isdigit(formatChar)) {
- width = strtoul(format, &end, 10);
- format = end;
- formatChar = *format;
- }
- if (formatChar == 'l') {
- storeLong = TRUE;
- format++;
- formatChar = *format;
- }
- if (formatChar == 'h') {
- storeShort = TRUE;
- format++;
- formatChar = *format;
- }
-
- /*
- * Skip any leading blanks in the input (except for 'c' format).
- * Also, default the width to infinity, except for 'c' format.
- */
-
- if ((formatChar != 'c') && (formatChar != '[')) {
- while (isspace(streamChar)) {
- streamChar = getc(stream);
- }
- }
- if ((width <= 0) && (formatChar != 'c')) {
- width = 1000000;
- }
-
- /*
- * Check for EOF again after parsing away the white space.
- */
- if (streamChar == EOF) {
- break;
- }
-
- /*
- * Process the conversion character. For numbers, this just means
- * turning it into a "base" number that indicates how to read in
- * a number.
- */
-
- base = -1;
- switch (formatChar) {
-
- case '%':
- if (streamChar != '%') {
- goto done;
- }
- streamChar = getc(stream);
- break;
-
- case 'D':
- storeShort = FALSE;
- case 'd':
- base = 10;
- break;
-
- case 'O':
- storeShort = FALSE;
- case 'o':
- base = 8;
- break;
-
- case 'X':
- storeShort = FALSE;
- case 'x':
- base = 16;
- break;
-
- case 'E':
- case 'F':
- storeLong = TRUE;
- case 'e':
- case 'f':
- base = 0;
- break;
-
- /*
- * Characters and strings are handled in exactly the same way,
- * except that for characters the default width is 1 and spaces
- * are not considered terminators.
- */
-
- case 'c':
- if (width <= 0) {
- width = 1;
- }
- case 's':
- if (suppress) {
- while ((width > 0) && (streamChar != EOF)) {
- if (isspace(streamChar) && (formatChar == 's')) {
- break;
- }
- streamChar = getc(stream);
- width--;
- }
- } else {
- ptr = va_arg(args, char *);
- while ((width > 0) && (streamChar != EOF)) {
- if (isspace(streamChar) && (formatChar == 's')) {
- break;
- }
- *ptr = streamChar;
- ptr++;
- streamChar = getc(stream);
- width--;
- }
- if (formatChar == 's') {
- *ptr = 0;
- }
- assignedFields++;
- }
- break;
-
- case '[':
- format++; formatChar = *format;
- if (formatChar == '^') {
- format++;
- }
- if (!suppress) {
- firstPtr = ptr = va_arg(args, char *);
- }
- savedPtr = format;
- while ((width > 0) && (streamChar != EOF)) {
- format = savedPtr;
- while (TRUE) {
- if (*format == streamChar) {
- if (formatChar == '^') {
- goto stringEnd;
- } else {
- break;
- }
- }
- if ((*format == ']') || (*format == 0)) {
- if (formatChar == '^') {
- break;
- } else {
- goto stringEnd;
- }
- }
- format++;
- }
- if (!suppress) {
- *ptr = streamChar;
- ptr++;
- }
- streamChar = getc(stream);
- width--;
- }
- stringEnd:
- if (ptr == firstPtr) {
- goto done;
- }
- while ((*format != ']') && (*format != 0)) {
- format++;
- }
- formatChar = *format;
- if (!suppress) {
- *ptr = 0;
- assignedFields++;
- }
- break;
-
- /*
- * Don't ask why, but for compatibility with UNIX, a null
- * conversion character must always return EOF, and any
- * other conversion character must be treated as decimal.
- */
-
- case 0:
- ungetc(streamChar, stream);
- return(EOF);
-
- default:
- base = 10;
- break;
- }
-
- /*
- * If the field wasn't a number, then everything was handled
- * in the switch statement above. Otherwise, we still have
- * to read in a number. This gets handled differently for
- * integers and floating-point numbers.
- */
-
- if (base < 0) {
- continue;
- }
-
- if (streamChar == '-') {
- sign = TRUE;
- width -= 1;
- streamChar = getc(stream);
- } else {
- sign = FALSE;
- if (streamChar == '+') {
- width -= 1;
- streamChar = getc(stream);
- }
- }
-
- /*
- * If we're supposed to be parsing a floating-point number, read
- * the digits into a temporary buffer and use the conversion library
- * routine to convert them.
- */
-
- #define COPYCHAR \
- *ptr = streamChar; ptr++; width--; streamChar = getc(stream);
-
- if (base == 0) {
- if (width > MAX_FLOAT_SIZE) {
- width = MAX_FLOAT_SIZE;
- }
- ptr = buf;
- while ((width > 0) && isdigit(streamChar)) {
- COPYCHAR;
- }
- if ((width > 0) && (streamChar == '.')) {
- COPYCHAR;
- }
- while ((width > 0) && isdigit(streamChar)) {
- COPYCHAR;
- }
- if ((width > 0) && ((streamChar == 'e') || (streamChar == 'E'))) {
- COPYCHAR;
- if ((width > 0) &&
- ((streamChar == '+') || (streamChar == '-'))) {
- COPYCHAR;
- }
- while ((width > 0) && isdigit(streamChar)) {
- COPYCHAR;
- }
- }
- *ptr = 0;
-
- if (ptr == buf) { /* Not a valid number. */
- goto done;
- }
-
- if (!suppress) {
- double d;
- d = atof(buf);
- if (sign) {
- d = -d;
- }
- if (storeLong) {
- *(va_arg(args, double *)) = d;
- } else {
- *(va_arg(args, float *)) = d;
- }
- assignedFields++;
- }
- } else {
- /*
- * This is an integer. Use special-purpose code for the
- * three supported bases in order to make it run fast.
- */
-
- int i;
- int anyDigits;
-
- i = 0;
- anyDigits = FALSE;
- if (base == 10) {
- while ((width > 0) && isdigit(streamChar)) {
- i = (i * 10) + (streamChar - '0');
- streamChar = getc(stream);
- anyDigits = TRUE;
- width -= 1;
- }
- } else if (base == 8) {
- while ((width > 0) && (streamChar >= '0')
- && (streamChar <= '7')) {
- i = (i << 3) + (streamChar - '0');
- streamChar = getc(stream);
- anyDigits = TRUE;
- width -= 1;
- }
- } else {
- while (width > 0) {
- if (isdigit(streamChar)) {
- i = (i << 4) + (streamChar - '0');
- } else if ((streamChar >= 'a') && (streamChar <= 'f')) {
- i = (i << 4) + (streamChar + 10 - 'a');
- } else if ((streamChar >= 'A') && (streamChar <= 'F')) {
- i = (i << 4) + (streamChar + 10 - 'A');
- } else {
- break;
- }
- streamChar = getc(stream);
- anyDigits = TRUE;
- width--;
- }
- }
- if (!anyDigits) {
- goto done;
- }
- if (sign) {
- i = -i;
- }
- if (!suppress) {
- if (storeShort) {
- *(va_arg(args, short *)) = i;
- } else {
- *(va_arg(args, int *)) = i;
- }
- assignedFields++;
- }
- }
- }
-
- done:
- ungetc(streamChar, stream);
- if ((streamChar == EOF) && (assignedFields == 0)) {
- return(EOF);
- }
- return(assignedFields);
- }
- @
-
-
- 1.5
- log
- @Use function prototypes. Lint.
- @
- text
- @d17 1
- a17 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/stdio/RCS/vfscanf.c,v 1.4 89/09/15 12:08:48 douglis Exp Locker: kupfer $ SPRITE (Berkeley)";
- d88 1
- a88 1
- char *savedPtr, *end;
- d268 1
- a268 1
- ptr = va_arg(args, char *);
- d298 3
- @
-
-
- 1.5.1.1
- log
- @Initial branch for Sprite server.
- @
- text
- @d17 1
- a17 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/stdio/RCS/vfscanf.c,v 1.5 90/09/11 14:27:16 kupfer Exp Locker: rab $ SPRITE (Berkeley)";
- @
-
-
- 1.4
- log
- @fixed bug with encountering EOF reading a string
- @
- text
- @d17 1
- a17 1
- static char rcsid[] = "$Header: /sprite/src/lib/c/stdio/RCS/vfscanf.c,v 1.3 88/07/25 13:12:45 ouster Exp Locker: douglis $ SPRITE (Berkeley)";
- d20 1
- d87 1
- a87 1
- register char *ptr;
- @
-
-
- 1.3
- log
- @Lint.
- @
- text
- @d17 1
- a17 1
- static char rcsid[] = "$Header: vfscanf.c,v 1.2 88/07/21 09:36:33 ouster Exp $ SPRITE (Berkeley)";
- d175 7
- @
-
-
- 1.2
- log
- @Change from _doscan to vfscanf.
- @
- text
- @d17 1
- a17 1
- static char rcsid[] = "$Header: vfscanf.c,v 1.1 88/06/10 16:23:37 ouster Exp $ SPRITE (Berkeley)";
- d20 4
- a23 4
- #include "stdio.h"
- #include "ctype.h"
- #include "stdlib.h"
- #include "varargs.h"
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d2 1
- a2 1
- * _doscan.c --
- d4 1
- a4 1
- * Source code for the "_doscan" library procedure.
- d17 1
- a17 1
- static char rcsid[] = "$Header: atoi.c,v 1.1 88/04/28 17:20:23 ouster Exp $ SPRITE (Berkeley)";
- d41 1
- a41 1
- * _doscan --
- d60 2
- a61 1
- _doscan(format, args, stream)
- d65 1
- a65 1
- va_list *args; /* Addresses of a variable number of arguments
- a66 1
- register FILE *stream; /* Where to read characters for parsing. */
- d237 1
- a237 1
- ptr = va_arg(*args, char *);
- d260 1
- a260 1
- ptr = va_arg(*args, char *);
- d384 1
- a384 1
- *(va_arg(*args, double *)) = d;
- d386 1
- a386 1
- *(va_arg(*args, float *)) = d;
- d440 1
- a440 1
- *(va_arg(*args, short *)) = i;
- d442 1
- a442 1
- *(va_arg(*args, int *)) = i;
- @
-